
/* File name	: run.c
 * Project 		: BKIT MCR
 * Version 		: 1.0
 * Creation Date: 07/07/2010
 * Tabsize		: 4
 * Author  		: BKIT4U                   
 * Copyright	: (c) 2010 BKIT HARDWARE CLUB - www.bkit4u.com
 * License		: Free.
 * Comments		: 
 * 
 */

/*===================================*/
/*  Include                          */
/*===================================*/
#include    "run.h"
#include	"../led/led.h"
#include	"../input/input.h"
#include	"../handle/handle.h"
#include	"../timer/timer.h"
#include	"../adc/adc.h"
#include	"../speed/speed.h"
#include	"../beep/beep.h"

/*====================================*/
/*	Global Variable Declaration       */
/*====================================*/
int speed_run_forward;
const char rate[45] ={ 100,	98,96,95,93,91,90,88,86,85,83,
							82,80,79,77,75,74,73,71,70,68,
							67,65,64,62,61,59,58,57,55,54,
							52,51,49,48,47,45,44,42,41,39,
							38,36,35,33	};


/*====================================*/
/*  Function name: run                */
/*  Parameter: null                   */
/*  Description: this is the function */
/*               to run application   */
/*====================================*/
void run( void )
{
    int pattern;
    handle( 0 );
    speed( 0, 0 );
    pattern = 0;
	
	switch (get_dipsw())
	{
		case 0: // 25 %
			speed_run_forward = 60;
			break;
		case 1: // 30 %
			speed_run_forward = 60;
			break;
		case 2:
			speed_run_forward = 60;
			break;
		case 3: // 40 %
			speed_run_forward = 75;
			break;
		case 4:
			speed_run_forward = 90;
			break;
		case 5: // 50 %
			speed_run_forward = 105;
			break;
		case 6:
			speed_run_forward = 120;
			break;
		case 7: // 60 %
			speed_run_forward = 135;
			break;
		case 8:
			speed_run_forward = 150;
			break;
		case 9:      // 70 % 
			speed_run_forward = 165;
			break;
		case 10:
			speed_run_forward = 180;
			break;
		case 11: // 80 %
			speed_run_forward = 195;
			break;
		case 12:
			speed_run_forward = 210;
			break;
		case 13: // 90 %
			speed_run_forward = 225;
			break;
		case 14:
			speed_run_forward = 240;
			break;
		case 15: // 100%
			speed_run_forward = 255;
			break;
		
	}

    while( 1 ) {
    switch( pattern ) {

    /*****************************************************************
    About pattern
     0: Switch input wait
     1: Wait for 1 second after the switch is pressed.
    11: Usual trace
    12: Check for the end of long turn to the right
    13: Check for the end of long turn to the left
    21: Processing when first crossline is detected
    22: Skip second crossline
    23: Trace 1 after crossline
    24: Trace 2 after crossline, crank detection
    31: Left crank Clear process  Waits till it stabilizes
    32: Left crank clear process   Check for end of turn
    41: Right crank clear process  Waits till it stabilizes
    42: Right crank clear process  Check for end of turn
    *****************************************************************/

    case 0:
        /* Switch input waiting */
        if( get_extkey() ) {
            pattern = 1;
            cnt1 = 0;
            break;
        }
        if( cnt1 < 100 ) {              /* LED blinking process */
            ext_led_put( 0x1 );
        } else if( cnt1 < 200 ) {
            ext_led_put( 0x2 );
        } else {
            cnt1 = 0;
        }
        break;

    case 1:
        /* 1 second waiting after the switch is pushed */
        if( cnt1 < 500 ) {
            /* 1.0 seconds starting ago LED1:"OFF" , LED0:"ON" */
            ext_led_put( 0x1 );
        } else if( cnt1 < 1000 ) {
            /* 0.5 seconds starting ago LED1:"ON" , LED0:"OFF" */
            ext_led_put( 0x2 );
        } else {
            /* Start!! */
            ext_led_put( 0x0 );
            pattern = 11;
            cnt1 = 0;
        }
        break;

    case 11:
        /* Usual trace */
        if( check_crossline() ) {       /* Crossline Check */
            pattern = 21;
            break;
        }
        switch( sensor_inp(MASK3_3) ) {
            case 0x00:
                /* Center -> Straight */
                handle( 0 );
                speed( 200 ,200 );
                break;

            case 0x04:
                /* Slightly left inclined -> Slight turn to the right */
                handle( 5 );
                speed( 150 ,150 );
                break;

            case 0x06:
                /* Little left inclined -> Small turn to the right */
                handle( 10 );
                speed( 80 ,69 );
                break;

            case 0x07:
                /* Left inclined from the middle -> Middle turn to the right */
                handle( 15 );
                speed( 50 ,40 );
                break;

            case 0x03:
                /* Large inclined to the left -> Large turn to the right */
                handle( 25 );
                speed( 30 ,21 );
                pattern = 12;
                break;

            case 0x20:
                /* Slightly inclined to the right -> Slight turn to the left */
                handle( -5 );
                speed( 100 ,100 );
                break;

            case 0x60:
                /* A little inclined to the right -> Small turn to the left */
                handle( -10 );
                speed( 69 ,80 );
                break;

            case 0xe0:
                /* Right inclined from the middle veering -> Middle turn to the left */
                handle( -15 );
                speed( 40 ,50 );
                break;

            case 0xc0:
                /* Large inclined to the right -> Large turn to the left */
                handle( -25 );
                speed( 21 ,30 );
                pattern = 13;
                break;

            default:
                break;
        }
        break;

    case 12:
        /* Check of large turning to the right completion */
        if( check_crossline() ) {   /* Crossline check even during turning */
            pattern = 21;
            break;
        }
        if( sensor_inp(MASK3_3) == 0x06 ) {
            pattern = 11;
        }
        break;

    case 13:
        /* Check of large turning completion to the left */
        if( check_crossline() ) {   /* Crossline check even during large turn */
            pattern = 21;
            break;
        }
        if( sensor_inp(MASK3_3) == 0x60 ) {
            pattern = 11;
        }
        break;

    case 21:
        /* Process when first crossline is detected */
        ext_led_put( 0x3 );
        handle( 0 );
        speed( 0 ,0 );
        pattern = 22;
        cnt1 = 0;
        break;

    case 22:
        /* Second is skipped. */
        if( cnt1 > 100 ) {
            cnt1 = 0;
            pattern = 23;
        }
        break;

    case 23:
        /* 1 of trace after crossline */
        if( cnt1 > 300 ) {
            cnt1 = 0;
            pattern = 24;
            break;
        }
        switch( sensor_inp(MASK3_3) ) {
            case 0x00:
                /* Center -> Straight  */
                handle( 0 );
                speed( 40 ,40 );
                break;
            case 0x04:
            case 0x06:
            case 0x07:
            case 0x03:
                /* Tending to the left -> Turn to the right  */
                handle( 8 );
                speed( 40 ,36 );
                break;
            case 0x20:
            case 0x60:
            case 0xe0:
            case 0xc0:
                /* Tending to the right -> Turn to the left  */
                handle( -8 );
                speed( 36 ,40 );
                break;
            default:
                break;
        }
        break;

    case 24:
        /* 2 of trace after crossline and crank detection */
        switch( sensor_inp(MASK3_3) ) {
            case 0xe0:
                /* Judgment of left crank -> To the left crank clearing process */
                ext_led_put( 0x1 );
                handle( -38 );
                speed( 10 ,50 );
                pattern = 31;
                cnt1 = 0;
                break;
            case 0x07:
                /* Judgment of right crank -> The process for getting over right crank */
                ext_led_put( 0x2 );
                handle( 38 );
                speed( 50 ,10 );
                pattern = 41;
                cnt1 = 0;
                break;
            case 0x00:
                /* Center -> Straight */
                handle( 0 );
                speed( 40 ,40 );
                break;
            case 0x04:
            case 0x06:
            case 0x03:
                /* Tending to the left -> Turn to the right */
                handle( 8 );
                speed( 40 ,36 );
                break;
            case 0x20:
            case 0x60:
            case 0xc0:
                /* Tending to the right -> Turn to the left */
                handle( -8 );
                speed( 36 ,40 );
                break;
            default:
                break;
        }
        break;

    case 31:
        /* Left crank clear process Wait a little till it becomes stable. */
        if( cnt1 > 200 ) {
            pattern = 32;
            cnt1 = 0;
        }
        break;

    case 32:
        /* Left crank clear process Check of end of turn */
        if( sensor_inp(MASK3_3) == 0x60 ) {
            ext_led_put( 0x0 );
            pattern = 11;
            cnt1 = 0;
        }
        break;

    case 41:
        /* Right crank clear processing Waits a little until stabilizing */
        if( cnt1 > 200 ) {
            pattern = 42;
            cnt1 = 0;
        }
        break;

    case 42:
        /* Right crank clear processing Turning completion check */
        if( sensor_inp(MASK3_3) == 0x06 ) {
            ext_led_put( 0x0 );
            pattern = 11;
            cnt1 = 0;
        }
        break;

    default:
        /* When the pattern is not applied to any case, return to waiting state */
        pattern = 0;
        break;
    }
    }
}

/*==============================================*/
/*  Function name: check_crossline    			*/
/*  Parameter: null                   			*/
/*  Return value: int                 			*/
/*  Description:1.Used to recognize   			*/
/*               cross line           			*/
/*              2. return 0:not line, 			*/
/*                        1:line      			*/
/*==============================================*/
int check_crossline( void )
{
    unsigned char b;

	b = sensor_inp(MASK2_2);
	switch (b)	
	{
		case 0x66:
			return 1;
		default :  return 0;
	}  
  
}

/*==============================================*/
/*  Function name: check_crosshalfline			*/
/*  Parameter: null                   			*/
/*  Return value: int                 			*/
/*  Description:1. Used to recognize  			*/
/*                    cross half line			*/
/*              2. return 0: not haft line		*/
/*                        1: right haft line	*/
/*						 -1: left half line     */
/*==============================================*/
int check_crosshalfline(void)
{
	if (check_crossline() == 0 ){
		if (sensor_inp(MASK3_3)==0xe0)
			return -1;
		if (sensor_inp(MASK3_3)==0x07)
			return 1;
	}
	return 0;
}

/*==============================================*/
/*  Function name: sensor_inp					*/
/*  Parameter: mask                   			*/
/*  Return value: unsigned char        			*/
/*  Description: return sensor value  			*/
/*==============================================*/
unsigned char sensor_inp (unsigned char MASK)
{
	return bit_change(sensor) & MASK;
}
/*==============================================*/
/*  Function name: bit_change					*/
/*  Parameter: in                   			*/
/*  Return value: unsigned char        			*/
/*  Description: return changed bit  			*/
/*==============================================*/
char unsigned bit_change( char unsigned in )
{
    unsigned char ret = 0;
    int i;
    for( i=0; i<8; i++ ) {
        ret >>= 1;                      /* Right shift of return value  */
        ret |= in & 0x80;               /* Ret bit7 = in bit7           */
        in  <<= 1;                      /* Left shift of argument       */
    }
    return ret;
}



/****************END FILE**************/

